<template>
    <a-form ref='formRef' :model='model' v-bind='attrs' :rules='rules'>
        <template v-for='field in FIELDS' :key='field.name'>
            <template v-if='field.hidden'>
                <a-form-item style='display:none' :label='field.label' :name='field.name'>
                    <a-input type='hidden' v-model:value='model[field.name]'></a-input>
                </a-form-item>
            </template>
            <template v-else>
                <a-form-item :label='field.label' :name='field.name'>
                    <template v-if='slots[field.name]'>
                        <slot :name='field.name' :value='model[field.name]'></slot>
                    </template>
                    <template v-else>
                        <template v-if='field.type == undefined || field.type == "text"'>
                            <a-input :class='$style.input' type='text' autocomplete='off' :show-count='field.maxlength != undefined' allowClear v-bind='field.attrs' :maxlength='field.maxlength' v-model:value='model[field.name]' />
                        </template>
                        <template v-else-if='field.type == "number"'>
                            <a-input :class='$style.input' type='number' autocomplete='off' allowClear v-bind='field.attrs' :min='field.min' :max='field.max' v-model:value.number='model[field.name]' />
                        </template>
                        <template v-else-if='field.type == "password"'>
                            <a-input-password :class='$style.input' :show-count='field.maxlength != undefined' autocomplete='off' allowClear v-bind='field.attrs' :maxlength='field.maxlength' v-model:value='model[field.name]' />
                        </template>
                        <template v-else-if='field.type == "textarea"'>
                            <a-textarea :class='$style.input' autocomplete='off' :show-count='field.maxlength != undefined' allowClear v-bind='field.attrs' :maxlength='field.maxlength' v-model:value='model[field.name]' />
                        </template>
                        <template v-else-if='field.type == "select"'>
                            <a-select :class='$style.input' allowClear :filter-option="filterOption" v-bind='field.attrs' v-model:value='model[field.name]' :options='field._options'></a-select>
                        </template>
                        <template v-else-if='field.type == "langSelect"'>
                            <LangSelect :class='$style.input' v-model='model[field.name]' />
                        </template>
                        <template v-else-if='field.type == "radio"'>
                            <a-radio-group v-bind='field.attrs' v-model:value='model[field.name]'>
                                <template v-for='option in field._options'>
                                    <a-radio :value='option.value'>{{option.label}}</a-radio>
                                </template>
                            </a-radio-group>
                        </template>
                        <template v-else-if='field.type == "treeSelect"'>
                            <a-tree-select :class='$style.input' allowClear v-bind='field.attrs' v-model:value='model[field.name]' :fieldNames='{children : field.childrenField || "children", label : field.labelField || "title", value : field.valueField || "value"}' :treeData='field._options'></a-tree-select>
                        </template>
                        <template v-else-if='field.type == "switch"'>
                            <a-switch v-bind='field.attrs' v-model:checked='model[field.name]' :options='field._options'></a-switch>
                        </template>
                        <template v-else-if='field.type == "datePicker"'>
                            <a-date-picker :class='$style.input' v-bind='field.attrs' v-model:value='model[field.name]' />
                        </template>
                        <template v-else-if='field.type == "rangePicker"'>
                            <a-range-picker :class='$style.input' v-bind='field.attrs' v-model:value='model[field.name]' />
                        </template>
                        <template v-else-if='field.type == "timeRrangePicker"'>
                            <a-time-range-picker :class='$style.input' valueFormat='HH:mm:ss' v-bind='field.attrs' v-model:value='model[field.name]' />
                        </template>
                        <template v-else-if='field.type == "upload"'>
                            <a-upload list-type='picture-card' v-model:file-list='model[field.name]' :beforeUpload='beforeUpload' :customRequest='e => customRequest(e, field)'>
                                <template v-if='model[field.name].length < field.uploadCount'>
                                    <PlusOutlined />
                                </template>
                            </a-upload>
                        </template>
                        <!-- <template v-else-if='field.type == "selectWin"'>
                            <div :class='$style.selectWin'>
                                <template v-if='model[field.name]'><span>{{typeof model[field.name] == 'object' ? model[field.name].label : model[field.name]}}</span></template>
                                <template v-else><span :class='$style.placeholder'>选择{{field.label}}</span></template>
                                <SelectArrow :class='$style.selectIcon' @click='openSelectWin(field, model[field.name])' />
                            </div>
                        </template> -->
                    </template>
                </a-form-item>
            </template>
        </template>
    </a-form>

    <!-- <Beleport to='body'>
        <a-drawer v-model:visible='drawerVisible' :class='$style.drawer' width='auto'>
            <template v-for='field in fields' :key='field.name'>
                <template v-if='field.type == "selectWin"'>
                    <template v-if='currentDrawer == field.name'>
                        <slot :name='"selectWin-" + field.name' :value='model[field.name]' :field='field'></slot>
                    </template>
                </template>
            </template>

            <template #footer>
                <a-button style='margin-right: 8px' @click='closeSelectWin'>{{$translate('cancel')}}</a-button>
                <a-button type='primary' @click='confirmSelectWin'>{{$translate('confirm')}}</a-button>
            </template>
        </a-drawer>
    </teleport> -->
    

</template>

<script lang='ts' setup>
    import { reactive, ref, toRefs, computed, useAttrs, useSlots } from "vue";
    import { UploadProps } from "ant-design-vue";
    import { PlusOutlined } from "@ant-design/icons-vue";
    import { SelectArrow } from '@/components/icon'
    import { useI18nStore } from "@/store/i18n";
    import LangSelect from './LangSelect.vue'

    const props = defineProps<{
        fields : FormField[];
        [key:string] : any;
    }>()

    const emit = defineEmits<{
        (e : 'openSelectWin', field:FormField, value:any) : void;
    }>()

    const { fields } = toRefs(props)
    const slots = useSlots()

    const i18n = useI18nStore()

    const attrs = useAttrs()
    const drawerVisible = ref(false)
    const currentDrawer = ref()
    const currentField = ref<FormField | null>()

    const formRef = ref()

    const model = ref<{[key:string] : any}>({})
    const rules = ref<{[key:string] : any}>({})

    const FIELDS = reactive<FormField[]>([])

    fields.value.forEach(async (field) => {
        if(field.ignore) return
        const item = reactive<FormField>({...field, _options : []})
        FIELDS.push(item)
        
        if(item.type == 'upload' && item.defaultValue.length > 0) {
            model.value[item.name] = []
            item.defaultValue.forEach((url, i) => {
                model.value[item.name].push({
                    uid : 'u' + i,
                    name: 'n' + i,
                    status: 'done',
                    url : import.meta.env.B_IMAGE_URL + url,
                    value : url

                })
            })
        }else {
            model.value[item.name] = item.defaultValue != undefined ? item.defaultValue : ''
        }

        if(field.hidden) return
        

        if((item.type == 'select' || item.type == 'treeSelect' || item.type == 'radio') && item.options) {
            let options:any
            if(typeof item.options == 'function') {
                options = await item.options()
            }else {
                options = item.options
            }

            if(item.type == 'treeSelect') {
                item._options = options
            }else {
                const _options:any[] = []

                if(Array.isArray(options)) {
                    options.forEach(option => {
                        if(typeof option == 'object') {
                            _options.push({
                                label : option[item.labelField as string],
                                value : option[item.valueField as string]
                            })
                        }else {
                            _options.push({
                                label : option,
                                value : option
                            })
                        }
                        
                    })
                    
                }else {
                    for(let k in options) {
                        _options.push({
                            label : options[k],
                            value : item.valueFormat ? item.valueFormat(k) : k
                        })
                    }
                }

                item._options = _options
            }
            
            
        }

        if(item.required) {
            if(!item.rules) {
                rules.value[item.name] = [
                    {
                        required : true,
                        trigger : 'change',
                        validator(_rule: any, value: any) {
                            if(value === '' || value === null) {
                                return Promise.reject(
                                    ((item.type == 'text' || item.type == undefined || item.type == 'password' || item.type == 'number' || item.type == 'textarea') ? i18n.concat('input', 'input') : i18n.concat('please', 'select')) + item.label
                                )
                            }

                            if(item.type == 'number') {
                                value = Number(value)
                                if(item.min != undefined && value < item.min) {
                                    return Promise.reject(item.label + i18n.concat('cannot', 'lessThan') + item.min)
                                }

                                if(item.max != undefined && value > item.max) {
                                    return Promise.reject(item.label + i18n.concat('cannot', 'greaterThan') + item.max)
                                }
                            }

                            return Promise.resolve()
                        }
                    }
                ]
            }
        }

        if(item.rules) {
            rules.value[item.name] = item.rules
        }
    })
    

    



    function filterOption(input:string, options) {
        return options.label.indexOf(input) >= 0;
    }

    

    function beforeUpload(file:File, field:FormField) {
        return true
    }
    function customRequest(e, field:FormField) {
        field.uploadApi(e.file).then(res => {
            let len = model.value[field.name].length
            model.value[field.name][len-1].status = 'done'
            model.value[field.name][len-1].url = import.meta.env.B_IMAGE_URL + res
            model.value[field.name][len-1].value = res
        })
    }


    function openSelectWin(field:FormField, value:any) {
        currentDrawer.value = field.name
        drawerVisible.value = true
        currentField.value = field
        //emit('openSelectWin', field, value)
    }
    
    function closeSelectWin() {
        drawerVisible.value = false
        currentDrawer.value = ''
        currentField.value = null
    }

    async function confirmSelectWin() {
        model.value[currentDrawer.value] = await currentField.value?.select()
        closeSelectWin()
    }


    defineExpose({
        clearValidate() {
            return formRef.value.clearValidate()
        },
        resetFields() {
            return formRef.value.resetFields()
        },
        validate() {
            return formRef.value.validate()
        }
    })

</script>


<style lang='scss' module>
    .input{
        width: 100%;
    }

    .placeholder{
        color: rgba(0, 0, 0, 0.25);
    }

    .selectWin{
        height: 32px;
        display: flex;
        justify-content: space-between;
        align-items: center;

        .selectIcon{
            color: #d9d9d9;
            font-size: 20px;
            cursor: pointer;
        }
    }

    .drawer{
        :global(.ant-drawer-content-wrapper) {
            min-width: 378px;
        }
        
    }
</style>